package com.spring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * Created by dong peng on 2017/11/12.
 *
 * 使用注解配置aop
 *
 * @Aspect表示此类是一个切面类
 * @Before 表示一个通知，前置通知
 * execution 是一个切点
 * 表达式是连接点
 *
 */
@Aspect
@Component
public class AopProxy {

    /**
     * 定义一个公共的切点
     */
//    @Pointcut("execution(* com.spring.aop..*.sayHello(..))")
//    public void performance() {
//    }
//    @Before("performance()")
//    public void log(){
//        System.out.println("test aop print.......................");
//    }


    /**
     * 表达式切入
     */
    @Before("execution(* com.spring.aop..*.sayHello(..))")
    public void log(){
        System.out.println("test aop print.......................");
    }

    /**
     * 注解切入
     */
    @Before("@annotation(MyException)")
    public void annotation(){
        System.out.println("基于注解切入  aop  开始.......................");
    }

    /**
     * 目标方法执行完后调用
     */
    @AfterReturning("execution(* com.spring.aop..*.sayHello(..))")
    public void applause() {
        System.out.println("CLAP CLAP CLAP");
    }

    /**
     * 目标方法发生异常时调用
     *
     * 处理抛出异常ex
     */
    @AfterThrowing(throwing="ex", pointcut = "execution(* com.spring.aop..*.sayHello(..))")
    public void demandRefund(Throwable ex) {
        System.out.println("Demanding a refund"+ex.getMessage());
    }

    /**
     * 环绕通知
     * @param jp 通过它调用目标方法
     */
//    @Around("execution(* com.spring.aop..*.sayHello(..))")
    @Around("@annotation(MyException)")
    public Object watchPerformance(ProceedingJoinPoint jp) {

        Object result = null;
        try {
            System.out.println("环绕通知，处理开始...");
             result = jp.proceed();
            System.out.println("环绕通知，处理结束");

        } catch (Throwable e) {
            System.out.println("环绕通知处理异常");
            e.printStackTrace();
        }

        return result;
    }

}
